package com.nidu.demo.user.gatewayimpl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.PageQuery;
import com.alibaba.cola.dto.PageResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nidu.demo.user.dto.UserListQry;
import com.nidu.demo.user.dto.UserPageQry;
import com.nidu.demo.user.convertor.UserConvertor;
import com.nidu.demo.user.gateway.UserGateway;
import com.nidu.demo.user.mapper.UserMapper;
import com.nidu.demo.user.mapper.dataobject.UserDO;
import com.nidu.demo.user.model.User;
import com.nidu.demo.user.model.UserCriteria;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Set;
import java.util.List;

@Component
@RequiredArgsConstructor
public class UserGatewayImpl implements UserGateway {
    
    private final UserMapper mapper;
    private final UserConvertor convertor;

    @Override
    public User create(User user) {
        UserDO userDO = convertor.toDataObject(user);
        mapper.insert(userDO);
        return convertor.toDomainObject(userDO);
    }

    @Override
    public User update(User user) {
        UserDO userDO = convertor.toDataObject(user);
        mapper.updateById(userDO);
        return convertor.toDomainObject(userDO);
    }

    @Override
    public void deleteById(Long id) {
        mapper.deleteById(id);
    }

    @Override
    public void deleteByIds(Set<Long> ids) {
        mapper.deleteByIds(ids);
    }

    @Override
    public User getById(Long id) {
        UserDO userDO = mapper.selectById(id);
        if(userDO == null){
            return null;
        }
        return convertor.toDomainObject(userDO);
    }

    @Override
    public List<User> getByIds(Set<Long> ids) {
        LambdaQueryWrapper<UserDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(UserDO::getId, ids);
        List<UserDO> userDOS = mapper.selectList(wrapper);
        if(CollUtil.isEmpty(userDOS)){
            return new ArrayList<>();
        }
        return convertor.toDomainObjects(userDOS);
    }

    @Override
    public User getByUsername(String username) {
        UserDO userDO = mapper.selectByUsername(username);
        if(userDO == null){
            return null;
        }
        return convertor.toDomainObject(userDO);
    }

    @Override
    public User getByMobile(String mobile) {
        UserDO userDO = mapper.selectByMobile(mobile);
        if(userDO == null){
            return null;
        }
        return convertor.toDomainObject(userDO);
    }

    @Override
    public User getByEmail(String email) {
        UserDO userDO = mapper.selectByEmail(email);
        if(userDO == null){
            return null;
        }
        return convertor.toDomainObject(userDO);
    }

    @Override
    public List<User> listByCondition(UserCriteria criteria) {
        LambdaQueryWrapper<UserDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(criteria.getStatus() != null, UserDO::getStatus, criteria.getStatus());
        wrapper.in(!CollUtil.isEmpty(criteria.getUserIds()), UserDO::getId, criteria.getUserIds());

        wrapper.eq(!StrUtil.isEmpty(criteria.getUsername()), UserDO::getUsername, criteria.getUsername());
        wrapper.eq(!StrUtil.isEmpty(criteria.getMobile()), UserDO::getMobile, criteria.getMobile());
        wrapper.eq(!StrUtil.isEmpty(criteria.getEmail()), UserDO::getMobile, criteria.getEmail());
        wrapper.eq(criteria.getCompanyId() != null, UserDO::getCompanyId, criteria.getCompanyId());
        List<UserDO> userDOS = mapper. selectList(wrapper);
        if(CollUtil.isEmpty(userDOS)){
            return new ArrayList<>();
        }
        return convertor.toDomainObjects(userDOS);
    }

    @Override
    public PageResponse<User> pageByCondition(UserCriteria criteria) {
        // 创建查询条件
        LambdaQueryWrapper<UserDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(criteria.getStatus() != null, UserDO::getStatus, criteria.getStatus());
        wrapper.in(!CollUtil.isEmpty(criteria.getUserIds()), UserDO::getId, criteria.getUserIds());

        LocalDateTime[] createTime = criteria.getCreateTime();
        if (createTime != null) {
            if (createTime.length == 1 && createTime[0] != null) {
                wrapper.ge(UserDO::getCreateTime, createTime[0]);
            } else if (createTime.length > 1 && createTime[0] != null && createTime[1] != null) {
                wrapper.between(UserDO::getCreateTime, createTime[0], createTime[1]);
            }
        }

        wrapper.eq(!StrUtil.isEmpty(criteria.getUsername()), UserDO::getUsername, criteria.getUsername());
        wrapper.eq(!StrUtil.isEmpty(criteria.getMobile()), UserDO::getMobile, criteria.getMobile());
        wrapper.eq(!StrUtil.isEmpty(criteria.getEmail()), UserDO::getEmail, criteria.getEmail());
        wrapper.eq(criteria.getCompanyId() != null, UserDO::getCompanyId, criteria.getCompanyId());

        // 创建分页对象，确保使用 UserDO
        Page<UserDO> page = new Page<>(criteria.getPageIndex(), criteria.getPageSize());

        // 排序字段
        if (!StrUtil.isEmpty(criteria.getOrderBy())) {
            if (PageQuery.DESC.equals(criteria.getOrderDirection())) {
                page.addOrder(OrderItem.desc(criteria.getOrderBy()));
            } else {
                page.addOrder(OrderItem.asc(criteria.getOrderBy()));
            }
        }
        // 执行分页查询
        mapper.selectPage(page, wrapper);
        List<User> users = convertor.toDomainObjects(page.getRecords());
        return PageResponse.of(users, (int)page.getTotal(), (int)page.getSize(), (int)page.getCurrent());
    }

    @Override
    public void updatePassword(Long id, String password) {
        UserDO userDO = new UserDO();
        userDO.setId(id);
        userDO.setPassword(password);
        mapper.updateById(userDO);
    }

    @Override
    public void updateStatus(Long id, Integer status) {
        UserDO userDO = new UserDO();
        userDO.setId(id);
        userDO.setStatus(status);
        mapper.updateById(userDO);
    }

    @Override
    public void updateLoginInfo(Long id, String loginIp) {
        UserDO userDO = new UserDO();
        userDO.setId(id);
        userDO.setLoginIp(loginIp);
        userDO.setLoginTime(LocalDateTime.now());
        mapper.updateById(userDO);
    }

    @Override
    public void updateProfile(Long id, String nickname, String email, Integer gender) {
        UserDO userDO = new UserDO();
        userDO.setId(id);
        if(StrUtil.isEmpty(nickname)){
            userDO.setNickname(nickname);
        }
        if(StrUtil.isEmpty(email)){
            userDO.setEmail(email);
        }
        if(gender != null){
            userDO.setGender(gender);
        }
        mapper.updateById(userDO);
    }

    @Override
    public void updateAvatar(Long id, String avatar) {
        UserDO userDO = new UserDO();
        userDO.setId(id);
        userDO.setAvatar(avatar);
        mapper.updateById(userDO);
    }

} 